package cn.wolfcode.shop.cloud.service.impl;


import cn.wolfcode.shop.cloud.common.BusinessException;
import cn.wolfcode.shop.cloud.common.Result;
import cn.wolfcode.shop.cloud.domain.Goods;
import cn.wolfcode.shop.cloud.domain.SeckillGood;
import cn.wolfcode.shop.cloud.feign.GoodsFeignApi;
import cn.wolfcode.shop.cloud.mapper.SeckillGoodMapper;
import cn.wolfcode.shop.cloud.msg.SeckillCodemsg;
import cn.wolfcode.shop.cloud.redis.RedisService;
import cn.wolfcode.shop.cloud.service.ISeckillGoodService;
import cn.wolfcode.shop.cloud.util.SeckillKeyPrefixUtil;
import cn.wolfcode.shop.cloud.vo.SeckillGoodVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;


@Service
public class SeckillGoodServiceImpl implements ISeckillGoodService {
    @Autowired
    private SeckillGoodMapper seckillGoodMapper;

    @Autowired
    private GoodsFeignApi goodsFeignApi;
    @Autowired
    private RedisService redisService;

    @Override
    public List<SeckillGoodVO> query() {
        //查询出来秒杀商品数据
        List<SeckillGood> seckillGoods = seckillGoodMapper.list();
        return common(seckillGoods);
    }

    public List<SeckillGoodVO> common(List<SeckillGood> seckillGoods) {
        //把商品的id1放到set集合中
        Set<Long> goodIds = new HashSet<>();
        for (SeckillGood seckillGood : seckillGoods) {
            goodIds.add(seckillGood.getGoodId());
        }
        //根据id集合远程调用商品服务查询数据
        Result<List<Goods>> result = goodsFeignApi.queryGoods(goodIds);
        if (result != null && result.getCode() != 200) {
            throw new BusinessException(SeckillCodemsg.REMOTE_GOODS_ERROR);
        }
        List<Goods> data = (List<Goods>) result.getData();
        //在内存中进行聚合操作
        Map<Long, Goods> map = new HashMap<>();
        for (Goods goods : data) {
            map.put(goods.getId(), goods);
        }
        //返回List<vo>
        ArrayList<SeckillGoodVO> vos = new ArrayList<>();
        for (SeckillGood seckillGood : seckillGoods) {
            SeckillGoodVO vo = new SeckillGoodVO();
            Goods goods = map.get(seckillGood.getGoodId());
            BeanUtils.copyProperties(goods, vo);
            BeanUtils.copyProperties(seckillGood, vo);
            vos.add(vo);
        }
        return vos;
    }


    @Override
    public SeckillGoodVO queryById(Long seckillId) {
        SeckillGood seckillGood = seckillGoodMapper.queryById(seckillId);
        ArrayList<SeckillGood> list = new ArrayList<>();
        list.add(seckillGood);
        List<SeckillGoodVO> common = common(list);
        return common.get(0);
    }

    @Override
    public int decr(Long seckillId) {
        return seckillGoodMapper.decr(seckillId);
    }

    @Override
    public SeckillGoodVO queryByIdCache(Long seckillId) {
        SeckillGoodVO vo = redisService.hget(SeckillKeyPrefixUtil.SECKILL_HASH, "", seckillId + "", SeckillGoodVO
                .class);
        //从redis中把内容取出来
        Integer count = redisService.get(SeckillKeyPrefixUtil.SECKILL_STOCK_COUNT, "" + seckillId, Integer.class);
        if (count < 0) {
            count =0;
        }
        vo.setStockCount(count);
        return vo;
    }

    @Override
    public List<SeckillGoodVO> queryCache() {
        Map<String, SeckillGoodVO> map = redisService.hgetAll(SeckillKeyPrefixUtil.SECKILL_HASH,
                "", SeckillGoodVO.class);
        Collection<SeckillGoodVO> values = map.values();
        ArrayList<SeckillGoodVO> vos = new ArrayList<>(values);

        for (SeckillGoodVO vo : vos) {
            //从redis中把内容取出来
            Integer count = redisService.get(SeckillKeyPrefixUtil.SECKILL_STOCK_COUNT, "" + vo.getId(), Integer.class);
            if (count < 0) {
                count =0;
            }
            vo.setStockCount(count);
        }
        return vos;
    }

    @Override
    public void incrCount(Long seckillId) {
        seckillGoodMapper.incrCount(seckillId);
    }

    @Override
    public void syncPreCount(Long seckillId) {
        SeckillGoodVO vo = queryById(seckillId);
         redisService.set(SeckillKeyPrefixUtil.SECKILL_STOCK_COUNT, "" + seckillId, vo.getStockCount());
    }


}
